<?php

namespace hangman;

use \mg\Profile;
use \mg\Application;
use \mg\Actions;
use \mg\get;
use \mg\SessionInjection;

/**
 * Empty Profile
 */
class HangmanProfile extends Profile {
	
}

interface HangmanActions extends Actions {

	/**
	 * @param get $character The character guessed 
	 */
	public function guess(get $character = null);

	/**
	 * Start a new game
	 */	
	public function start();
}

class HangmanApplication extends Application implements HangmanActions {

	public $guesses = null;
	public $word = null;
	public $tries = null;
	
	private $lastGuessCorrect = null;

	/**
	 * Set up session variables
	 */
	public function inject() {
		$this->guesses = new SessionInjection(array());
		$this->word = new SessionInjection(null);
		$this->tries = new SessionInjection(0);
	}

	/**
	 * @return true when the last guess was correct, false when the last guess was incorrect and null if there was no last guess
	 */
	public function lastGuessCorrect() {
		return $this->lastGuessCorrect;
	}

	/**
	 * @return int the number of remaining guesses
	 */
	public function getRemainingGuesses() {
		return max(0, 6 - $this->tries);
	}

	/**
	 * @return true when the game is finished
	 */
	public function isFinished() {
		return $this->hasWon() || $this->getRemainingGuesses() === 0;
	}

	/**
	 * @return true when the player has won the game
	 */
	public function hasWon() {
		$hasAllCharacters = true;

		for($i = 0, $c = mb_strlen($this->word); $i < $c && $hasAllCharacters; $i++) {
			$hasAllCharacters = in_array($this->word[$i], $this->guesses);
		}

		return $hasAllCharacters;
	}

	/**
	 * {@inheritDoc}
	 */
	public function guess(get $character = null) {
		if($this->isFinished()) { return; }
		if($character === null) { return; }

		$character = mb_strtolower($character->getValue());

		if(!preg_match('|^[a-z]$|', $character)) { return; }
		if(in_array($character, $this->guesses)) { return; }

		$this->guesses[] = $character;
		
		if(mb_stripos($this->word, $character) === false) {
			$this->tries++;
			$this->lastGuessCorrect = false;
		} else {
			$this->lastGuessCorrect = true;
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public function start() {
		$this->word = 'mangrove';
		$this->guesses = array();
		$this->tries = 0;
	}

}